#include "types.h"
#include "params.h"
#include "memory.h"
#include "biscuit.h"
#include "kfunc.h"
#include "lock.h"
#include "kalloc.h"
#include "proc.h"
#include "traphdlr.h"
#include "kobj.h"
#include "util.h"
#include "syscall.h"

// extern struct trapframe * tf;

int
sys_fork () {
    return fork ();
}

int
sys_riskfork () {
    return riskfork ();
}

int
sys_exec (int path, int arg) {
    struct proc * p;
    //char * arg = (char*) argi;
    int retval;
    p = myproc ();
    //printk ("path:%p, arg:%p\n", path, arg);
    //panic ("sys_exec");
    char execpath [MAX_NAMESZ];
    char execarg[MAX_NAMESZ];
    bzero (execpath, sizeof (execpath));
    bzero (execarg, sizeof (execarg));
    vmread (p->pgtb, path, execpath, MAX_NAMESZ);
    //printk ("path: %s\n", execpath);
    if (arg!=0)
        vmread (p->pgtb, arg, execarg, MAX_NAMESZ); // error
    //printk ("exec:%p", exec);
    //panic ("sys_exec");
    execpath[MAX_NAMESZ-1] = 0;
    execarg[MAX_NAMESZ-1] = 0;
    // panic ("before kernel exec handler");
    retval = exec (execpath, execarg);
    // panic ("sys_exec");
    return retval;
}

int
sys_wait () {
    return wait ();
}

int
sys_dup (int fd) {
    return dup (fd);
}

int
sys_open (int path) {
    struct proc * p;
    p = myproc ();
    char openpath [MAX_NAMESZ];
    vmread (p->pgtb, path, openpath, MAX_NAMESZ);
    openpath [MAX_NAMESZ - 1] = 0;
    return open (openpath);
}

int
sys_read (int fd, int buf, int sz) {
    return read (fd, (char*)buf, sz);
}

int
sys_write (int fd, int buf, int sz) {
    // printk ("sp : %p\n", ll_r_sp());
    // panic ("Write");
    return write (fd, (char*)buf, sz);
}

int
sys_close (int fd) {
    return close (fd);
}

int
sys_pipe (int fds) {
    return pipe (fds);
}

int
sys_exit () {
    exit ();
    return 0;
}

int
sys_rm (int path) {
    struct proc * p;
    p = myproc ();
    char rmpath [MAX_NAMESZ];
    vmread (p->pgtb, path, rmpath, MAX_NAMESZ);
    rmpath [MAX_NAMESZ-1] = 0;
    return rm (rmpath);
}

int
sys_ls (int buf) {
    return ls ((char*)buf);
}


int
syscall (int n, int a0, int a1, int a2) {
    // printk ("syscall1");
    int retval = -1;
    struct proc *p;
    p = myproc ();
    switch (n) {
        case SYS_FORK: {
            retval = sys_fork ();
            break;
        }
        case SYS_RISKFORK: {
            retval = sys_riskfork ();
            break;
        }
        case SYS_EXEC: {
            retval = sys_exec (a0, a1);
            break;
        }
        case SYS_WAIT:{
            retval = sys_wait ();
            break;
        }
        case SYS_DUP:{
            retval = sys_dup (a0);
            break;
        }
        case SYS_OPEN:{
            retval = sys_open (a0);
            break;
        }
        case SYS_PIPE:{
            retval = sys_pipe (a0);
            break;
        }
        case SYS_READ:{
            retval = sys_read (a0, a1,a2);
            break;
        }
        case SYS_WRITE:{
            retval = sys_write (a0, a1, a2);
            break;
        }
        case SYS_CLOSE:{
            retval = sys_close (a0);
            break;
        }
        case SYS_RM:{
            retval = sys_rm (a0);
            break;
        }
        case SYS_LS:{
            retval = sys_ls (a0);
            break;
        }
        case SYS_EXIT:{
            retval = sys_exit ();
            break;
        }
        default:
        break;
    }
    p->tf->a0 = retval; // 返回值
    return retval;
}
